//
//  PlayLayer.m
//  MinusTheBox
//
//  Created by Chi Ho Chiu on 15/4/12.
//  Copyright 2012 Individual. All rights reserved.
//

#import "PlayLayer.h"

@implementation PlayLayer
@synthesize delegate;
@synthesize spritesArray;
@synthesize spritesState;
@synthesize runningSprite;

-(void) dealloc
{
	[spritesArray release];
	[super dealloc];
}

#pragma mark - init
-(id) initWithMaxStep:(int)val withDelegate:(id<PlayLayerDelegate>)layerDelegate
{
	if( self = [super init] )
	{
		self.isTouchEnabled = YES;
		self.spritesState = kSPRITE_STATE_NIL;
		self.spritesArray = [Box2DArray node];
		self.runningSprite = 0;
		self.delegate = layerDelegate;
		
		CGSize winSize = [[CCDirector sharedDirector] winSize];
		
		//Background Image
		CCSprite *bg = [CCSprite spriteWithFile:@"mainmenu_bg.png"];
		bg.position = ccp(winSize.width/2, winSize.height/2);
		[self addChild:bg];
		
		//Title
		CCLabelBMFont *titleLabel = [CCLabelBMFont labelWithString:[NSString stringWithFormat:@"Stage %d", [GameManager sharedGameManager].currentLevel] fntFile:@"Dakota_white_24.fnt"];
		titleLabel.position = ccp(winSize.width/2, winSize.height - 20 );
		
		//Back Button
        CCLabelBMFont *backFont = [CCLabelBMFont labelWithString:@"Back" fntFile:@"Dakota_white_16.fnt"];
        CCMenuItem *backItem = [CCMenuItemLabel itemWithLabel:backFont target:delegate selector:@selector(onSelectedBack:)];
        
		//Back To Previous Step Button
        CCLabelBMFont *backStepFont = [CCLabelBMFont labelWithString:@"Back Step" fntFile:@"Dakota_white_16.fnt"];
        CCMenuItem *backStepItem = [CCMenuItemLabel itemWithLabel:backStepFont target:delegate selector:@selector(onSelectedBackToPreviousStep:)];
		backStepItem.tag = kTAG_BACK_STEP_MENU_ITEM;
		
        CCMenu *leftMenu = [CCMenu menuWithItems:backItem, backStepItem, nil];
        [leftMenu alignItemsVertically];
        [leftMenu setPosition: ccp(20, winSize.height - 20 )];
		leftMenu.tag = kTAG_LEFT_MENU;
		
		//Hint Button
		CCLabelBMFont *hintFont = [CCLabelBMFont labelWithString:@"Hint" fntFile:@"Dakota_white_16.fnt"];
        CCMenuItem *hintItem = [CCMenuItemLabel itemWithLabel:hintFont target:delegate selector:@selector(onSelectedHint:)];
		hintItem.tag = KTAG_HINT_MENU_ITEM;
		
		CCMenu *rightMenu = [CCMenu menuWithItems:hintItem, nil];
		[rightMenu alignItemsVertically];
		[rightMenu setPosition: ccp(winSize.width - 20, winSize.height - 20 )];
		rightMenu.tag = kTAG_RIGHT_MENU;
		
		//Step Label
		CCLabelBMFont *stepFont = [CCLabelBMFont labelWithString:[NSString stringWithFormat:@"0 / %d Steps", val] fntFile:@"Dakota_white_24.fnt"];
		[stepFont setPosition:ccp(winSize.width/2, 20)];
		stepFont.tag = kTAG_STEP_LABEL;
		
		//Add Child
		[self addChild:titleLabel];
		[self addChild:leftMenu];
		[self addChild:rightMenu];
		[self addChild:stepFont];
	}
	
	return self;
}

-(void) registerWithTouchDispatcher
{
	[[[CCDirector sharedDirector] touchDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];
}

-(void) placeBox:(Box2DArray *)boxArray
{
	for(int column = 0; column < MAX_BOX_COLUMN; column++)
	{
		for(int row = 0; row < MAX_BOX_ROW; row++)
		{
			id obj = [boxArray getObjectInColumn:column row:row];
			if(obj != [NSNull null])
			{
				NSNumber *valObj = (NSNumber *)obj;
				int value = [valObj intValue];	//Get the box value
				CCSprite *box = [CCSprite spriteWithFile:[NSString stringWithFormat:@"box_%hi.png", value]];	//Create the box sprite
				box.position = ccp( LEFT_BOTTOM_X + BOX_WIDTH * column, LEFT_BOTTOM_Y + BOX_HEIGHT * row);
				[self addChild:box];
				
				[spritesArray addObjectInColumn:column row:row value:box];	//Add to Box2DArray
			}
		}
	}

}

-(void) removeAllBox
{
	for(int col = 0; col < MAX_BOX_COLUMN; col++)
	{
		for(int row = 0; row < MAX_BOX_ROW; row++)
		{
			id obj = [spritesArray getObjectInColumn:col row:row];
			if(obj != [NSNull null])
			{
				CCSprite *box = (CCSprite *)obj;
				[box removeFromParentAndCleanup:YES];	//Remove from UI
				[spritesArray updateObjectInColumn:col row:row value:[NSNull null]];	//Set back to nil
			}
		}
	}
}

#pragma mark - Box interation
-(void) updateBoxNumberFrom:(int)oriVal to:(int)newVal inColumn:(int)col inRow:(int)row
{
	self.spritesState = kSPRITE_STATE_MINUS;
	runningSprite++;
	
	//Get the BoxSprite
	CCSprite *box = [spritesArray getObjectInColumn:col row:row];
		
	//TODO: Enhance update Box Number Action
	
	//Change box image
	[box setTexture:[[CCTextureCache sharedTextureCache] addImage:[NSString stringWithFormat:@"box_%hi.png", newVal]]];
	
	//CCCallFuncND *action1 = [CCCallFuncND actionWithTarget:self selector:@selector(changeSpriteNumber:data:) data:valObj];
	CCCallFuncN *action2 = [CCCallFuncN actionWithTarget:self selector:@selector(onActionCompleted:)];
	[box runAction:[CCSequence actions: action2, nil]];
	
}

-(void) fallBoxInColumn:(int)oriCol fromRow:(int)oriRow toRow:(int)newRow
{
	self.spritesState = KSPRITE_STATE_FALL;
	runningSprite++;
	
	CCSprite *box = [spritesArray getObjectInColumn:oriCol row:oriRow];
	
	int rowDiff = oriRow - newRow;
	float duractionEachBox = 0.2;
	
	CCMoveBy *action1 = [CCMoveBy actionWithDuration:(duractionEachBox *rowDiff) position:CGPointMake(0, -rowDiff * BOX_HEIGHT)];
	CCCallFuncN *action2 = [CCCallFuncN actionWithTarget:self selector:@selector(onActionCompleted:)];
	[box runAction:[CCSequence actions:action1, action2, nil]];
	
	//Update the spritesArray Model
	[spritesArray updateObjectInColumn:oriCol row:newRow value:box];
	[spritesArray removeObjectInColumn:oriCol row:oriRow];
}

-(void) chainBoxInColumn:(int)col row:(int)row 
{
	self.spritesState = kSPRITE_STATE_EXPLODE_CHAIN;
	runningSprite++;
	
	CCSprite *box = [spritesArray getObjectInColumn:col row:row];
	
	float duractionEachBox = 0.5;
	
	CCScaleTo *action1 = [CCScaleTo actionWithDuration:duractionEachBox scale:0];
	CCCallFuncN *action2 = [CCCallFuncN actionWithTarget:self selector:@selector(onActionCompleted:)];
	[box runAction:[CCSequence actions:action1, action2, nil]];
	
	[spritesArray removeObjectInColumn:col row:row];
}

-(void) explodeZeroBoxInColumn:(int)col row:(int)row
{
	self.spritesState = kSPRITE_STATE_EXPLODE_ZERO;
	runningSprite++;
	
	//Get the BoxSprite
	CCSprite *box = [spritesArray getObjectInColumn:col row:row];
	
	//CCCallFuncND *action1 = [CCCallFuncND actionWithTarget:self selector:@selector(removeBoxFromLayer:data:) data:pos];
	float duractionEachBox = 0.5;
	
	CCScaleTo *action1 = [CCScaleTo actionWithDuration:duractionEachBox scale:0];
	CCCallFuncN *action2 = [CCCallFuncN actionWithTarget:self selector:@selector(onActionCompleted:)];
	[box runAction:[CCSequence actions:action1, action2, nil]];
	
	//TODO: Enhance Explode Zero Box Action
	[spritesArray removeObjectInColumn:col row:row];
}

#pragma mark - Other UI interaction
-(void) showBackToPreviousStepSprite:(BOOL)bIsShow
{
	CCMenu *menu = (CCMenu *)[self getChildByTag:kTAG_LEFT_MENU];
	CCMenuItem *backStepItem = (CCMenuItem *)[menu getChildByTag:kTAG_BACK_STEP_MENU_ITEM];
	[backStepItem setVisible:bIsShow];
}

-(void) updateCurrentStep:(int)curStep maxStep:(int)maxStep
{
	CCLabelBMFont *stepFont = (CCLabelBMFont *)[self getChildByTag:kTAG_STEP_LABEL];
	[stepFont setString:[NSString stringWithFormat:@"%d / %d Steps", curStep, maxStep]];
}

-(void) setEnableTouch:(BOOL)isEnable
{
	self.isTouchEnabled = isEnable;
}

-(void) showHintBtn:(BOOL)show
{
	CCMenu *menu = (CCMenu *)[self getChildByTag:kTAG_RIGHT_MENU];
	CCMenuItem *hintItem = (CCMenuItem *)[menu getChildByTag:KTAG_HINT_MENU_ITEM];
	[hintItem setVisible:show];
}

#pragma mark - UIAction
-(void) onActionCompleted:(id)sender;
{
	runningSprite--;

	//Since need to wait for the sprite completed action before remove it
	//Therefore, remove it once action completed
	if(spritesState == kSPRITE_STATE_EXPLODE_ZERO || spritesState == kSPRITE_STATE_EXPLODE_CHAIN)
	{
		[self removeChild:sender cleanup:YES];	//Remove from layer
	}
	
	//Only call delegate when no more sprite is running
	//In other word, wait for the action completed before executing another action
	if(runningSprite != 0)
		return;
	
	switch (spritesState)
	{
		case kSPRITE_STATE_MINUS:
			[delegate onUpdatedBoxNumberCompleted];
			break;
		case kSPRITE_STATE_EXPLODE_ZERO:
			[delegate onExplodeZeroBoxCompleted];
			break;
		case KSPRITE_STATE_FALL:
			[delegate onFallBoxCompleted];
			break;
		case kSPRITE_STATE_EXPLODE_CHAIN:
			[delegate onChainBoxCompleted];
			break;
		default:
			break;
	}
}
/*
-(void) removeBoxFromLayer:(CCSprite *)sender data:(NSArray *)pos
{
	//Update spritesArray object to NULL
	int col = [[pos objectAtIndex:0] intValue];
	int row = [[pos objectAtIndex:1] intValue];
	[spritesArray updateObjectInColumn:col row:row value:[NSNull null]];
	
	//Remove from layer
	[self removeChild:sender cleanup:YES];
}

-(void) changeSpriteNumber:(CCSprite *)sender data:(NSNumber *)valObj
{
	//Update the image
	int newVal = [valObj intValue];
	[sender setTexture:[[CCTextureCache sharedTextureCache] addImage:[NSString stringWithFormat:@"box_%hi.png", newVal]]];
}
*/
#pragma mark - Touch
-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
	return YES;
}

-(void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event
{
	CGPoint location = [self convertTouchToNodeSpace:touch];
	
	for(int column = 0; column < MAX_BOX_COLUMN; column++)
	{
		for(int row = 0; row < MAX_BOX_ROW; row++)
		{
			id obj = [spritesArray getObjectInColumn:column row:row];
			//if(![obj isEqual:[NSNull null]])	//Check if there's any box
			if(obj != [NSNull null])
			{
				CCSprite *box = (CCSprite *)obj;
				if( CGRectContainsPoint(box.boundingBox, location) )	//Check if touch any box
				{
					[delegate onClickedBoxInColumn:column row:row];		
					break;
				}
			}
		}
	}
}

-(void) ccTouchCancelled:(UITouch *)touch withEvent:(UIEvent *)event
{
	[self ccTouchEnded:touch withEvent:event];
}

-(void) ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event
{
	
}
@end
